use time::{Duration};
use serde::{Deserialize, Serialize};
use crate::domain::entity::user_entity::UserEntity;
use crate::domain::map::UserTypeEnum;

/// UserTokenClaims 用户Jwt数据体
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct UserTokenClaims {
    /** 主键 */
    pub id: u64,
    /** 账号 */
    pub username: String,
    /** 用户类型：0-普通用户、1-超级管理员 */
    pub user_type: i8,
    /** 业务线权限，多个逗号分隔 */
    pub permission_biz: Option<String>,
    pub time:i64,
    // 过期时间 s单位
    pub exp:usize
}

impl UserTokenClaims {
    pub fn new(user: UserEntity, expire_time: i64) -> Self {
        let now = time::get_time();
        let exp = now + Duration::minutes(expire_time);
        Self {
            id: user.id,
            username: user.username,
            user_type: user.user_type,
            permission_biz: user.permission_biz,
            time: now.sec,
            exp: exp.sec as usize
        }
    }
}

/// UserRefreshTokenClaims 用户刷新Jwt数据体
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct UserRefreshTokenClaims {
    /** 主键 */
    pub id: u64,
    pub time:i64,
    pub exp:usize
}

impl UserRefreshTokenClaims {
    pub fn new(user_id: u64, expire_time: i64) -> Self {
        let now = time::get_time();
        let exp = now + Duration::minutes(expire_time);
        Self {
            id: user_id,
            time: now.sec,
            exp: exp.sec as usize,
        }
    }
}

/// CaptchaResponse 验证码响应
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct CaptchaResponse {
    #[serde(rename="captchaEnabled")]
    pub(crate) captcha_enabled: Option<bool>,
    pub img: String,
    pub uuid: String
}

/// UserLoginRequest 用户登陆请求
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct UserLoginRequest {
    // 账号
    pub username: String,
    // 密码
    pub password: String,
    // 验证码
    pub code: String,
    // 验证码key
    pub code_key: String,
}

/// UserLoginResponse 用户登陆响应
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct UserLoginResponse {
    // 认证 token
    pub access_token: String,
    // 刷新 token
    pub refresh_token: String,
    pub username: String,
    pub user_id: u64,
    /** 用户类型：0-普通用户、1-超级管理员 */
    pub user_type: i8,
    pub type_name: String,
}

impl UserLoginResponse {
    pub fn new(token: String, refresh_token: String, user: UserEntity) -> Self {
        let t: UserTypeEnum = user.user_type.into();
        Self {
            access_token: token,
            refresh_token,
            username: user.username,
            user_id: user.id as u64,
            user_type: user.user_type,
            type_name: t.to_string(),
        }
    }
}